package com.um2.simplexe.serveur.ui.util.controleUI.actionsGeneriques;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;

import com.um2.simplexe.serveur.ui.exec.ToutesLesMethodesServeur;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.menu.ControleurDeMenu;
import com.um2.simplexe.serveur.ui.util.controleUI.chargeur.menu.ControleurDePanneaux;


class ClientWorker implements Runnable 
{
	private Socket client;
	PrintWriter out = null;
	private ToutesLesMethodesServeur tlms = null ;
	
	
	public ClientWorker(Socket client,ToutesLesMethodesServeur tlms) 
	{
		this.client = client;
		this.tlms  = tlms ;
	}

	public void run()
	{
		String line = "";
		BufferedReader in = null;
		
		try
		{
			in = new BufferedReader(new InputStreamReader(client.getInputStream()));
			out = new PrintWriter(client.getOutputStream(), true);
		} 
		catch (IOException e)
		{
			System.err.println("Pb E/S");
		}

			try
			{
				String nombreDeLiges = in.readLine() ;
				System.out.println("reception de "+nombreDeLiges+" lignes ???");
				
				// si ce qu on a recut viens d un navigateur web:
				if (nombreDeLiges.startsWith("GET /"))
				{
					// alors on renvoie un message d identification
					envoyerMessage(calculerResultat("NAVIGATEUR_WEB\n"+nombreDeLiges)) ;
					out.close() ;
					client.close() ;
					return ;
				}
				
				for(int i=0;i<new Integer(nombreDeLiges);i++)
				{

					line += in.readLine()+"\n" ;
				} 
				System.out.println("reception de "+line+" "+client.getInetAddress()+"...\n");
			}
			catch (IOException e) 
			{
				System.err.println("Lecture ratee");
			}

			envoyerMessage(calculerResultat(line)) ;

		System.out.println("Fin envoi");
		
	}

	private String calculerResultat(String parametre) {
		
		// on decompose le parametre en 2
		// la fonction et le texte
		String fonctionDuParametre = "" ;
		String resteDuParametre = "" ;
		// la fontion est la premiere ligne:
		boolean trouveBackSlashN = false ;
		for (int i = 0; i < parametre.length(); i++) {
			// le premier '\n'
			if (!trouveBackSlashN && parametre.charAt(i)=='\n') {
				trouveBackSlashN = true ;
				
			}
			if (!trouveBackSlashN) {
				fonctionDuParametre+=parametre.charAt(i) ;
			}else {
				resteDuParametre+=parametre.charAt(i) ;
			}
		}
		
		for (ControleurDeMenu menu : tlms.getVectorPluginsMenus()) {
			if (menu.getPluginFonction().equalsIgnoreCase(fonctionDuParametre))
			{
				return menu.executePluginFonction(resteDuParametre) ;
			}
		}
		for (ControleurDePanneaux menu : tlms.getVectorPluginsPanneau()) {
			if (menu.getPluginFonction().equalsIgnoreCase(fonctionDuParametre))
			{
				return menu.executePluginFonction(resteDuParametre) ;
			}
		}

		return "resultat du calcul du simplexe impossible:\n pas de plugins pour effectuer <"+fonctionDuParametre+">" +
				"\n   pour le parametre <"+resteDuParametre+">" ;
	}

	private void envoyerMessage(String text) {
		
		
		int nombreLignesTexte = 1 ;
		for (int i = 0; i < text.length(); i++) {
			if (text.charAt(i)=='\n')
				nombreLignesTexte++ ;
		}
		
		out.println(nombreLignesTexte);
		out.println(text);
	}

	public String toString()
	{return client.getInetAddress().toString();}
}


public class SocketThrdServer implements Runnable
{
	private static final long serialVersionUID = 1L;
	public static SocketThrdServer frame = null ;
	private ServerSocket server = null;
	private static int port=4444;
	private static Vector<SocketThrdServer> lesteInstances = new Vector<SocketThrdServer> ();
	private ToutesLesMethodesServeur tlms = null ;

	private static Vector<ClientWorker> toutLesThreadsDEcoute = new Vector<ClientWorker> () ;
	
	public SocketThrdServer(ToutesLesMethodesServeur tlms)
	{
		this.tlms=tlms ;
		lesteInstances.add(this) ;
	}

	public void run()
	{
		try
		{
			server = new ServerSocket(port); 
		} 
		catch (IOException e) 
		{
			System.err.println("Peut pas ecoute le port "+getPort());
			return ;
		}
		System.out.println("Serveur lance.");
		while(true)
		{
			ClientWorker cw;
			try
			{
				System.out.println("ecoute sur le port "+port) ;
				cw = new ClientWorker(server.accept(),this.tlms);
				Thread t = new Thread(cw);
				t.start();
				toutLesThreadsDEcoute.add(cw) ;
			} 
			catch (IOException e)
			{
				System.err.println("Coupure de l ecoute du serveur");
				return ;
			}
		}
	}

	protected void finalize()
	{
		try
		{
			server.close();
			server = null ;
		} 
		catch (IOException e) 
		{
			System.err.println("Peut pas fermer la connexion");
		}
		catch (NullPointerException e) 
		{
		}
	}

	
	
	public static void coupeToutesLesConnexions() {
		System.out.println("coupure de toutes les connexions");
		for (ClientWorker cw : toutLesThreadsDEcoute) {
			new Thread(cw).interrupt() ;
		}
		for (SocketThrdServer s : lesteInstances) { 
			s.finalize() ;
		}
	}
	public static Runnable lanceEcoute(ToutesLesMethodesServeur tlms)
	{
		frame  = new SocketThrdServer(tlms);
//		frame.run();
		return frame ;
	}
	
	public static int getPort() 
	{return SocketThrdServer.port;}

	public static void setPort(int port)
	{SocketThrdServer.port = port;}
	
}

